//打补丁专用

/**
 * 打补丁函数patch(oldNode, vNode) 
 * @param {*} oldNode 指视图html已经写好的模板节点
 * @param {*} vNode AST生成的虚拟节点
 */
function patch(oldNode, vNode) {
  /**
   * console.log(vNode);
   * {
   *   el: div#app,
   *   tag: "div",
   *   text: undefined,
   *   children: (3) [{…}, {…}, {…}],
   *   props: {id: 'app', style: {…}}
   * }
   */

  let el = createElement(vNode),
    parentElement = oldNode.parentNode;

  //把el放到oldNode的后边
  //放到<script>的上方
  parentElement.insertBefore(el, oldNode.nextSibling);

  //移除旧的节点
  parentElement.removeChild(oldNode);
}

/**
 * 创建真实DOM节点
 */
function createElement(vnode) {

  const {
    tag,
    props,
    children,
    text
  } = vnode;

  //证明是标签名称且是一个元素节点 div/ span/...
  if (typeof tag === 'string') {

    //挂载真实节点
    vnode.el = document.createElement(tag);


    //更新属性
    updateProps(vnode);

    //遍历子标签以及属性
    //递归创建真实的子节点
    children.map((child) => {
      vnode.el.appendChild(createElement(child));
    });
  } else {
    //证明是文本节点
    vnode.el = document.createTextNode(text);
  }

  //返回挂载真实节点的el
  return vnode.el;
}

//负责处理更新属性
function updateProps(vnode) {
  const el = vnode.el,
    newProps = vnode.props || {};

  /**
   * console.log(newProps);
   * {id: 'app', style: {{color: ' red', " font-size": ' 20px'}}}
   * {class: 'text', style: {{color: 'green'}}}
   */

  //遍历
  for (let key in newProps) {
    // console.log(key); id/style/class

    if (key === 'style') {
      for (let sKey in newProps.style) {
        //这里设置 style="color: red; font-size: 20px;"
        // console.log(sKey); color / font-size

        //color: red /font-size: 20px
        el.style[sKey] = newProps.style[sKey];

      }
    } else if (key === 'class') {
      //这里设置 class="text"
      el.className = newProps.class;
    } else {
      //这里设置 id="app"
      el.setAttribute(key, newProps[key]);
    }
  }
}

export {
  patch
}